<template>
  <a-modal
    v-model:visible="visible"
    :title="formData && formData.id ? '修改菜单' :'新增菜单'"
    draggable
    :width="width"
    @cancel="handleCancel"
  >
    <a-form :model="formData" ref="formRef" auto-label-width>
      <a-spin :loading="loading">
        <a-row>
          <a-col :span="12">
            <a-form-item
              label="类型"
              field="type"
              :rules="[{required:true,message:'菜单类型不能为空'}]"
              :validate-trigger="['blur']"
            >
              <a-radio-group v-model="formData.type">
                <a-radio :value="1">目录</a-radio>
                <a-radio :value="2">菜单</a-radio>
                <a-radio :value="3">操作权限</a-radio>
              </a-radio-group>
            </a-form-item>
          </a-col>
          <a-col :span="12">
            <a-form-item
              label="上级菜单"
              field="parentId"
              :rules="[{required:true,message:'上级菜单不能为空'}]"
              :validate-trigger="['change']"
            >
              <a-tree-select
                allow-clear
                :data="treeData"
                v-model="formData.parentId"
                :field-names="{key:'id',title:'name'}"
                placeholder="请选择上级菜单"
                :allow-search="true"
                :filter-tree-node="filterTreeNode"
              ></a-tree-select>
            </a-form-item>
          </a-col>
          <a-col :span="12">
            <a-form-item
              label="菜单名称"
              field="name"
              :rules="[{required:true,message:'菜单名称不能为空'}]"
              :validate-trigger="['blur']"
            >
              <a-input v-model="formData.name" placeholder="请输入菜单名称" allow-clear />
            </a-form-item>
          </a-col>
          <a-col :span="12" v-if="formData.type == 1 || formData.type == 2">
            <a-form-item label="图标" field="icon">
              <a-input-group style="width: 100%">
                <a-input v-model="formData.icon" style="width:80%" placeholder="请选择图标" allow-clear />
                <a-button
                  type="primary"
                  @click="iconRef.showIconModal(formData.icon)"
                  style="width:20%"
                >
                  <template #icon>
                    <icon-select-all />
                  </template>
                  选择
                </a-button>
              </a-input-group>
            </a-form-item>
          </a-col>
          <a-col :span="12" v-if="formData.type != 3">
            <a-form-item
              label="菜单路径"
              field="path"
              :rules="[{required:true,message:'菜单路径不能为空'}]"
              :validate-trigger="['blur']"
            >
              <a-input v-model="formData.path" placeholder="请输入菜单路径" allow-clear />
            </a-form-item>
          </a-col>
          <a-col :span="12" v-if="formData.type == 2 ">
            <a-form-item
              label="组件路径"
              field="component"
              :rules="[{required:true,message:'组件路径不能为空'}]"
              :validate-trigger="['blur']"
            >
              <a-input v-model="formData.component" placeholder="请输入组件路径" allow-clear />
            </a-form-item>
          </a-col>
          <a-col :span="12" v-if="formData.type == 2">
            <a-form-item label="路由参数" field="query">
              <a-input v-model="formData.query" placeholder="请输入路由参数" allow-clear />
            </a-form-item>
          </a-col>
          <a-col :span="12" v-if="formData.type == 3">
            <a-form-item
              label="权限编码"
              field="perms"
              :rules="formData.type == 3 ?[{required:true,message:'权限编码不能为空'}]:[]"
              :validate-trigger="['blur']"
            >
              <a-input v-model="formData.perms" placeholder="请输入权限编码" allow-clear />
            </a-form-item>
          </a-col>
          <a-col :span="12">
            <a-form-item
              label="排序"
              field="sort"
              :rules="[{required:true,message:'排序不能为空'}]"
              :validate-trigger="['blur']"
            >
              <a-input-number
                v-model="formData.sort"
                placeholder="请输入排序"
                allow-clear
                :precision="0"
                :min="1"
              />
            </a-form-item>
          </a-col>
          <a-col :span="12" v-if="formData.type != 3">
            <a-form-item
              label="是否隐藏"
              field="hidden"
              :rules="[{required:true,message:'是否隐藏不能为空'}]"
              :validate-trigger="['blur']"
            >
              <a-radio-group v-model="formData.hidden">
                <a-radio :value="0">否</a-radio>
                <a-radio :value="1">是</a-radio>
              </a-radio-group>
            </a-form-item>
          </a-col>
          <a-col :span="12" v-if="formData.type != 3">
            <a-form-item
              label="重定向"
              field="redirect"
              :rules="[{required:true,message:'是否重定向不能为空'}]"
              :validate-trigger="['blur']"
            >
              <a-radio-group v-model="formData.redirect">
                <a-radio :value="0">否</a-radio>
                <a-radio :value="1">是</a-radio>
              </a-radio-group>
            </a-form-item>
          </a-col>
          <a-col :span="12">
            <a-form-item
              label="状态"
              field="status"
              :rules="[{required:true, message:'状态不能为空'}]"
              :validate-trigger="['blur']"
            >
              <a-switch
                type="round"
                v-model="formData.status"
                :checked-value="1"
                :unchecked-value="0"
              >
                <template #checked>{{ $t('searchTable.operation.enabled') }}</template>
                <template #unchecked>{{ $t('searchTable.operation.disabled') }}</template>
              </a-switch>
            </a-form-item>
          </a-col>
        </a-row>
      </a-spin>
    </a-form>
    <template #footer>
      <a-button
        style="margin-right: 8px"
        @click="handleCancel"
      >{{ $t('searchTable.columns.operations.close') }}</a-button>
      <a-button
        type="primary"
        @click="handleSubmit"
        :loading="loading"
      >{{ $t('searchTable.columns.operations.save') }}</a-button>
    </template>
    <iconSelector ref="iconRef" @iconCallBack="handleIcon" />
  </a-modal>
</template>
<script setup lang="ts">
import { ref, watch, nextTick } from 'vue';
import { useI18n } from 'vue-i18n';
import { Modal, Message } from '@arco-design/web-vue';
import pinyin from 'js-pinyin';
import {
  treeResource,
  saveResource,
  updateResource,
  ResourceData,
} from '@/api/sys/resource';

import iconSelector from '@/components/iconSelector/iconSelector.vue';

const { t } = useI18n();

const loading = ref(false);
const visible = ref(false);
const width = ref('calc(48%)');

const formRef = ref();
const formData = ref<ResourceData>({
  status: 0,
});

// 菜单树形结构数据
const treeData = ref<any>([]);

// 图片选择
const iconRef = ref();
const handleIcon = (icon: string) => {
  formData.value.icon = icon;
};

const changed = ref(false);

const emit = defineEmits({ onSearch: null });

// 打开弹窗
const onOpen = async (record: any) => {
  await fetchData(record);
  nextTick(() => {
    changed.value = false;
  });
  visible.value = true;
};

// 获取菜单树
const fetchData = async (record: any) => {
  const res = await treeResource({});
  treeData.value = res.data;
  const data: any = [
    {
      name: '顶级',
      id: 0,
      children: [],
    },
  ];
  if (res.data && res.data.length > 0) {
    data[0].children = res.data;
  }
  treeData.value = data;
  deleteTreeEle(treeData.value);
  if (record) {
    formData.value = JSON.parse(JSON.stringify(record));
    if (record.id) {
      addDisabled(treeData.value, 'id', formData.value.id);
    }
  } else {
    formData.value = {
      type: 1,
      sort: 1,
      hidden: 0,
      redirect: 0,
      status: 0,
    };
  }
};

//解决渲染问题
const deleteTreeEle = (tree: any[]) => {
  for (let i = 0; i < tree.length; i++) {
    delete tree[i].title;
    delete tree[i].icon;
    if (tree[i].children && tree[i].children.length > 0) {
      deleteTreeEle(tree[i].children);
    }
  }
};
const addDisabled = (tree: any[], nodeKey: any, nodeVal: any) => {
  for (let i = 0; i < tree.length; i++) {
    if (tree[i][nodeKey] && tree[i][nodeKey] === nodeVal) {
      tree[i].disabled = true;
      return true;
    }
    if (tree[i].children && tree[i].children.length > 0) {
      let flag = addDisabled(tree[i].children, nodeKey, nodeVal);
      if (flag && flag === true) {
        return true;
      }
    }
  }
};

const filterTreeNode = (input: string, nodeData: any) => {
  let text: any = nodeData.name;
  let text1 = pinyin.getFullChars(text).toLowerCase();
  let text2 = pinyin.getCamelChars(text).toLowerCase();
  let input1 = pinyin.getFullChars(input).toLowerCase();
  let input2 = pinyin.getCamelChars(input).toLowerCase();
  return text1.indexOf(input1) >= 0 || text2.indexOf(input2) >= 0;
};

// 确认
const handleSubmit = async () => {
  formRef.value.validate().then((result: any) => {
    // 校验不通过
    if (result) {
      return;
    }
    loading.value = true;
    if (formData.value.id) {
      updateResource(formData.value)
        .then(() => {
          onOk();
        })
        .finally(() => {
          loading.value = false;
        });
    } else {
      saveResource(formData.value)
        .then(() => {
          onOk();
        })
        .finally(() => {
          loading.value = false;
        });
    }
  });
};

// 确认
const onOk = () => {
  formRef.value.clearValidate();
  formData.value = {};
  visible.value = false;
  Message.success(t('operations.success'));
  emit('onSearch');
};

// 取消
const handleCancel = () => {
  if (!changed.value) {
    onCancel();
  } else {
    Modal.confirm({
      title: t('operations.cancel.title'),
      content: '',
      onOk() {
        onCancel();
      },
      onCancel() {
        visible.value = true;
      },
    });
  }
};

// 取消
const onCancel = () => {
  formRef.value.clearValidate();
  formData.value = {};
  visible.value = false;
};

// 抛出函数
defineExpose({
  onOpen,
});

// 监听数据
watch(
  formData,
  (newValue, oldValue) => {
    changed.value = true;
  },
  { deep: true }
);
</script>